/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frvar_field.h                                      */
/*  NOTE      =                                                    */
/*  DATE      = 2015/07/29 by yaohl                                */
/*******************************************************************/

#include "frcomm.h"
#include "frmem.h"
#include "frlist.h"

void frvarfield_free(Frvar_field **pp_varfiled)
{
    Frvar_field *p_st_field=NULL;
    Frbindata *p_st_value = NULL;

    if(pp_varfiled == NULL || *pp_varfiled == NULL)
        return ;

    p_st_field = *pp_varfiled;

    if(p_st_field->p_field_name)
    {
        frfree(p_st_field->p_field_name);
        p_st_field->p_field_name = NULL;
    }

    if(p_st_field->em_data_type == FRSTRING)
    {
        if(p_st_field->field_value.p_value)
            frfree(p_st_field->field_value.p_value);
    }
    if(p_st_field->em_data_type == FRBLOB || p_st_field->em_data_type == FRCLOB )
    {
        p_st_value = p_st_field->field_value.p_st_value;
        if(p_st_value)
        {
            if(p_st_value->p_data)
                frfree(p_st_value->p_data);
            frfree(p_st_value);
        }
    }
    frfree(p_st_field);
    *pp_varfiled = NULL;
    return;
}

Frvar_field *frvarfield_str(const char *p_key, const char *p_value)
{
    Frvar_field *p_st_field=NULL;
    if(p_key == NULL || p_value==NULL)
        return NULL;

    p_st_field = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_st_field == NULL)
        return NULL;
    memset(p_st_field, 0x00, sizeof(Frvar_field));
    p_st_field->p_field_name = frstrdup(p_key);
    p_st_field->em_data_type = FRSTRING;
    p_st_field->field_value.p_value = frstrdup(p_value);
    if(p_st_field->field_value.p_value == NULL)
        goto ERROR;

    return p_st_field;
ERROR:
    if(p_st_field)
    {
        if(p_st_field->em_data_type == FRSTRING && p_st_field->field_value.p_value)
            frfree(p_st_field->field_value.p_value);
        frfree(p_st_field);
    }

    return NULL;
}

Frvar_field *frvarfield_str2(char *p_key, const char *p_value, short s_flag_trunc)
{
    Frvar_field *p_st_field=NULL;
    if(p_key == NULL || p_value==NULL)
        return NULL;

    p_st_field = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_st_field == NULL)
        return NULL;
    memset(p_st_field, 0x00, sizeof(Frvar_field));
    p_st_field->p_field_name = p_key;
    p_st_field->em_data_type = FRSTRING;
    p_st_field->s_flag_trunc = s_flag_trunc;
    p_st_field->field_value.p_value = frstrdup(p_value);
    if(p_st_field->field_value.p_value == NULL)
        goto ERROR;

    return p_st_field;

ERROR:
    if(p_st_field)
    {
        if(p_st_field->em_data_type == FRSTRING && p_st_field->field_value.p_value)
            frfree(p_st_field->field_value.p_value);
        frfree(p_st_field);
    }

    return NULL;
}

Frvar_field *frvarfield_long2(char *p_key, long l_value)
{
    Frvar_field *p_st_field=NULL;
    if(p_key == NULL)
        return NULL;

    p_st_field = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_st_field == NULL)
        return NULL;
    memset(p_st_field, 0x00, sizeof(Frvar_field));
    p_st_field->p_field_name = p_key;
    p_st_field->em_data_type = FRLONG;
    p_st_field->s_flag_trunc = FR_NO;
    p_st_field->field_value.ll_value = l_value;

    return p_st_field;
}

Frvar_field *frvarfield_double2(char *p_key, double d_value)
{
    Frvar_field *p_st_field=NULL;
    if(p_key == NULL)
        return NULL;

    p_st_field = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_st_field == NULL)
        return NULL;
    memset(p_st_field, 0x00, sizeof(Frvar_field));
    p_st_field->p_field_name = p_key;
    p_st_field->em_data_type = FRDOUBLE;
    p_st_field->s_flag_trunc = FR_NO;
    p_st_field->field_value.d_value = d_value;

    return p_st_field;
}

Frvar_field *frvarfield_bin(const char *p_key
                          , const char *p_value
                          , unsigned int ui_len
                          , short s_flag_trunc)
{
    Frbindata *p_st_value = NULL;
    Frvar_field *p_st_field=NULL;
    if(p_key == NULL || ui_len<=0)
        return NULL;

    p_st_field = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_st_field == NULL)
        return NULL;
    memset(p_st_field, 0x00, sizeof(Frvar_field));
    p_st_field->p_field_name = frstrdup(p_key);
    p_st_field->em_data_type = FRBLOB;
    p_st_field->s_flag_trunc = s_flag_trunc;

    p_st_value = (Frbindata *)frmalloc(sizeof(Frbindata));
    if(p_st_value == NULL)
        goto ERROR;
    memset(p_st_value, 0x00, sizeof(Frbindata));
    if(p_value)
    {
        p_st_value->p_data = (char *) frmemdup(p_value, ui_len);
        if(p_st_value->p_data == NULL)
            goto ERROR;
    }
    p_st_value->ui_len = ui_len;
    p_st_field->field_value.p_st_value = p_st_value;

    return p_st_field;
ERROR:
    if(p_st_value)
    {
        if(p_st_value->p_data)
            frfree(p_st_value->p_data);
        frfree(p_st_value);
    }

    if(p_st_field)
        frfree(p_st_field);

    return NULL;
}

Frvar_field *frvarfield_clone(Frvar_field *p_varfield)
{
    Frvar_field *p_varfield_clone=NULL;
    Frbindata *p_st_value=NULL;

    if(p_varfield == NULL)
        return NULL;

    p_varfield_clone = (Frvar_field *)frmalloc(sizeof(Frvar_field));
    if(p_varfield_clone == NULL)
        return NULL;

    memset(p_varfield_clone, 0x00, sizeof(Frvar_field));
    p_varfield_clone->em_data_type = p_varfield->em_data_type;
    p_varfield_clone->p_field_name = frstrdup(p_varfield->p_field_name);

    switch(p_varfield->em_data_type)
    {
        case FRINT:
        case FRLONG:
        case FRFLOAT:
        case FRDOUBLE:
        case FRTIME:
        case FRBOOLEAN:
        case FRCHAR:
        case FRSHORT:
            memcpy(&p_varfield_clone->field_value, &p_varfield->field_value, sizeof(p_varfield_clone->field_value));
            return p_varfield_clone;
        case FRSTRING:
            p_varfield_clone->field_value.p_value = frstrdup(p_varfield->field_value.p_value);
            return p_varfield_clone;
        case FRBLOB:
        case FRCLOB:
            p_st_value = (Frbindata *) frmalloc(sizeof(Frbindata));
            if(p_st_value == NULL)
            {
                frfree(p_varfield_clone->p_field_name);
                frfree(p_varfield_clone);
                return NULL;
            }

            //FRBLOB,FRCLOB
            if(p_varfield->field_value.p_st_value->p_data)
                p_st_value->p_data = (char *) frmemdup(p_varfield->field_value.p_st_value->p_data, p_varfield->field_value.p_st_value->ui_len);
            else
                p_st_value->p_data = NULL;
            p_st_value->ui_len = p_varfield->field_value.p_st_value->ui_len;
            p_varfield_clone->field_value.p_st_value = p_st_value;

            return p_varfield_clone;
        default:
            return p_varfield_clone;
    }

    return p_varfield_clone;
}
